package org.pluslibs.framework.swingplus.jpanel;

import java.awt.FlowLayout;
import java.awt.Insets;

import javax.swing.JComponent;
import javax.swing.JLabel;
import javax.swing.JPanel;

import org.pluslibs.framework.swingplus.utils.BorderUtils;
import org.pluslibs.framework.swingplus.utils.JPanelUtils;

public class JPanelFields<T extends Enum<T>> extends JPanelGrid {

    private static final long serialVersionUID = 802644135012675950L;

    private static final Insets DEFAULT_INSETS = new Insets(0, 0, 3, 5);

    private static final int DEFAULT_MARGIN_X = -1;
    private static final int DEFAULT_MARGIN_Y = -1;

    private static final int DEFAULT_LABEL_COL = 0;
    private static final int DEFAULT_FIELD_COL = 1;

    private static final int DOUBLE_COL_WIDTH = 2;

    private final int labelCol;
    private final int fieldCol;

    public int getLabelCol() {
        return labelCol;
    }

    public JPanelFields() {
        this(null);
    }

    public JPanelFields(boolean border) {
        this(null, border);
    }

    public JPanelFields(String panelTitle) {
        this(panelTitle, DEFAULT_LABEL_COL, DEFAULT_FIELD_COL, DEFAULT_MARGIN_X, DEFAULT_MARGIN_Y, DEFAULT_INSETS);
    }

    public JPanelFields(String panelTitle, boolean border) {
        this(panelTitle, DEFAULT_LABEL_COL, DEFAULT_FIELD_COL, DEFAULT_MARGIN_X, DEFAULT_MARGIN_Y, DEFAULT_INSETS, border);
    }

    public JPanelFields(String panelTitle, int marginX, int marginY) {
        this(panelTitle, DEFAULT_LABEL_COL, DEFAULT_FIELD_COL, marginY, marginY, DEFAULT_INSETS);
    }

    public JPanelFields(String panelTitle, int labelCol, int fieldCol, int marginX, int marginY, Insets insets) {
        this(panelTitle, DEFAULT_LABEL_COL, DEFAULT_FIELD_COL, marginY, marginY, DEFAULT_INSETS, true);
    }

    public JPanelFields(String panelTitle, int labelCol, int fieldCol, int marginX, int marginY, Insets insets, boolean border) {
        super(insets);
        if (border) {
            BorderUtils.setTitledBorder(this, panelTitle, marginX, marginY);
        }
        this.labelCol = labelCol;
        this.fieldCol = fieldCol;
    }

    public void addField(JComponent component) {
        addField(null, component, false);
    }

    public void addField(JComponent component, int col, int fieldColWidth) {
        addField(component, col, fieldColWidth, insets, true);
    }

    public void addField(String strLabel, JComponent component) {
        addField(strLabel, component, false);
    }

    public void addField(T field, JComponent component) {
        addField(field.toString(), component);
    }

    public void addFields(String strLabel, JComponent... components) {
        JPanel panel = new JPanelPlus(new FlowLayout(FlowLayout.LEFT, 0, 0));

        int i = 0;
        for (JComponent jComponent : components) {
            panel.add(jComponent);
            if (i++ < components.length) {
                panel.add(new JLabel(" "));
            }
        }
        addField(strLabel, panel, false);
    }

    public void addField(String strLabel, JComponent component, boolean labelAbove) {
        addField(strLabel, component, labelAbove, DOUBLE_COL_WIDTH);
    }

    public void addField(String strLabel, JComponent component, boolean labelAbove, int fieldColWidth) {
        if (component == null) {
            throw new NullPointerException("Component Cannot be null");
        }
        addLabel(strLabel, true);
        int gridWidth = labelAbove ? fieldColWidth : SINGLE_COL_WIDTH;
        int col = labelAbove ? labelCol : fieldCol;
        addField(component, col, gridWidth, insets, labelAbove);
    }

    private void addLabel(String strLabel, boolean labelAbove) {
        if (strLabel == null) {
            addField(JPanelUtils.createEmpty(), labelCol, SINGLE_COL_WIDTH, insets, labelAbove);
        } else {
            addField(new JLabel(strLabel), labelCol, SINGLE_COL_WIDTH, insets, labelAbove);
        }
    }
}
